/**
 * 权限管理页面
 * 支持权限新增/编辑、批量删除、筛选
 */

import React from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Container } from '@/components/ui/container';
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  ResponsiveTable,
  ResponsiveTableHeader,
  ResponsiveTableRow,
  ResponsiveTableHead,
  ResponsiveTableCell,
  TableLoading,
  TableEmpty,
} from '@/components/ui/responsive-table';
import { TableBody } from '@/components/ui/table';
import { Checkbox } from '@/components/ui/checkbox';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  FormDialog,
  BatchActionBar,
} from '@/components/system';
import { PermissionForm } from './components/permission-form.jsx';
import { adminPermissionService } from '@/lib/api/services/admin-management-service.js';
import { useAdminMutation } from '@/hooks/use-admin-mutation.js';
import {
  ScrollText,
  Search,
  RefreshCw,
  Plus,
  EllipsisVertical,
  Edit,
  Trash2,
} from 'lucide-react';

const formatDateTime = (value) => {
  if (!value) return '-';
  try {
    return new Date(value).toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
    });
  } catch (error) {
    return value;
  }
};

export default function PermissionManagementPage() {
  const queryClient = useQueryClient();

  const [page, setPage] = React.useState(1);
  const [pageSize] = React.useState(20);
  const [keyword, setKeyword] = React.useState('');
  const [resource, setResource] = React.useState('all');
  const [action, setAction] = React.useState('all');
  const [category, setCategory] = React.useState('all');
  const [selectedIds, setSelectedIds] = React.useState([]);

  const [isCreateDialogOpen, setIsCreateDialogOpen] = React.useState(false);
  const [isEditDialogOpen, setIsEditDialogOpen] = React.useState(false);
  const [editingPermissionId, setEditingPermissionId] = React.useState(null);
  const [editingPermission, setEditingPermission] = React.useState(null);
  const [isLoadingPermissionDetail, setIsLoadingPermissionDetail] =
    React.useState(false);

  const queryParams = React.useMemo(() => {
    const params = { page, pageSize };
    if (keyword.trim()) params.keyword = keyword.trim();
    if (resource !== 'all') params.resource = resource;
    if (action !== 'all') params.action = action;
    if (category !== 'all') params.category = category;
    return params;
  }, [page, pageSize, keyword, resource, action, category]);

  const currentQueryKey = React.useMemo(
    () => ['admin-permissions', queryParams],
    [queryParams],
  );

  const {
    data: permissionsData,
    isLoading,
    error,
    refetch,
  } = useQuery({
    queryKey: currentQueryKey,
    queryFn: () => adminPermissionService.getList(queryParams),
    keepPreviousData: true,
  });

  const permissions = permissionsData?.data ?? [];
  const meta = {
    page: permissionsData?.page ?? page,
    pageSize: permissionsData?.pageSize ?? pageSize,
    total: permissionsData?.total ?? 0,
    totalPages: permissionsData?.totalPages ?? 1,
  };

  const resourceOptions = React.useMemo(() => {
    const set = new Set();
    permissions.forEach((item) => item.resource && set.add(item.resource));
    return ['all', ...Array.from(set)];
  }, [permissions]);

  const actionOptions = React.useMemo(() => {
    const set = new Set();
    permissions.forEach((item) => item.action && set.add(item.action));
    return ['all', ...Array.from(set)];
  }, [permissions]);

  const categoryOptions = React.useMemo(() => {
    const set = new Set();
    permissions.forEach((item) => item.category && set.add(item.category));
    return ['all', ...Array.from(set)];
  }, [permissions]);

  React.useEffect(() => {
    if (page > meta.totalPages && meta.totalPages > 0) {
      setPage(meta.totalPages);
    }
  }, [meta.totalPages, page]);

  React.useEffect(() => {
    setSelectedIds((prev) => {
      // 仅在已选权限失效时才更新，避免无意义的 state 更新触发无限渲染
      const filtered = prev.filter((id) =>
        permissions.some((permission) => permission.id === id),
      );
      const unchanged =
        filtered.length === prev.length &&
        filtered.every((id, index) => id === prev[index]);
      return unchanged ? prev : filtered;
    });
  }, [permissions]);

  const createPermissionMutation = useAdminMutation(
    (payload) => adminPermissionService.create(payload),
    {
      invalidateKeys: [['admin-permissions']],
      successMessage: '权限创建成功',
      onSuccess: () => {
        setIsCreateDialogOpen(false);
      },
    },
  );

  const updatePermissionMutation = useAdminMutation(
    ({ id, payload }) => adminPermissionService.update(id, payload),
    {
      invalidateKeys: [['admin-permissions']],
      successMessage: '权限信息已更新',
      onSuccess: () => {
        setIsEditDialogOpen(false);
        setEditingPermissionId(null);
        setEditingPermission(null);
      },
    },
  );

  const deletePermissionMutation = useAdminMutation(
    (id) => adminPermissionService.remove(id),
    {
      invalidateKeys: [['admin-permissions']],
      successMessage: '权限已删除',
      onMutate: async (id) => {
        await queryClient.cancelQueries({ queryKey: currentQueryKey });
        const previousData = queryClient.getQueryData(currentQueryKey);
        queryClient.setQueryData(currentQueryKey, (old) => {
          if (!old) return old;
          return {
            ...old,
            data: old.data.filter((permission) => permission.id !== id),
          };
        });
        return { previousData };
      },
      onError: (_error, _id, context) => {
        if (context?.previousData) {
          queryClient.setQueryData(currentQueryKey, context.previousData);
        }
      },
      onSuccess: (_data, id) => {
        setSelectedIds((prev) => prev.filter((item) => item !== id));
      },
      onSettled: () => {
        queryClient.invalidateQueries({ queryKey: ['admin-permissions'] });
      },
    },
  );

  const batchDeleteMutation = useAdminMutation(
    async ({ ids }) => {
      await Promise.all(ids.map((id) => adminPermissionService.remove(id)));
      return ids;
    },
    {
      invalidateKeys: [['admin-permissions']],
      successMessage: '已批量删除权限',
      onMutate: async ({ ids }) => {
        await queryClient.cancelQueries({ queryKey: currentQueryKey });
        const previousData = queryClient.getQueryData(currentQueryKey);
        queryClient.setQueryData(currentQueryKey, (old) => {
          if (!old) return old;
          return {
            ...old,
            data: old.data.filter((permission) => !ids.includes(permission.id)),
          };
        });
        return { previousData };
      },
      onError: (_error, _variables, context) => {
        if (context?.previousData) {
          queryClient.setQueryData(currentQueryKey, context.previousData);
        }
      },
      onSuccess: () => {
        setSelectedIds([]);
      },
      onSettled: () => {
        queryClient.invalidateQueries({ queryKey: ['admin-permissions'] });
      },
    },
  );

  const handleOpenEdit = React.useCallback(async (id) => {
    setEditingPermissionId(id);
    setIsEditDialogOpen(true);
    setIsLoadingPermissionDetail(true);
    try {
      const detail = await adminPermissionService.getDetail(id);
      setEditingPermission(detail);
    } catch (err) {
      toast.error(err?.message ?? '加载权限详情失败');
      setIsEditDialogOpen(false);
      setEditingPermissionId(null);
      setEditingPermission(null);
    } finally {
      setIsLoadingPermissionDetail(false);
    }
  }, []);

  const handleDelete = React.useCallback(
    (id) => {
      deletePermissionMutation.mutate(id);
    },
    [deletePermissionMutation],
  );

  const allRowIds = permissions.map((permission) => permission.id);
  const allSelected =
    allRowIds.length > 0 &&
    allRowIds.every((id) => selectedIds.includes(id));
  const partiallySelected =
    selectedIds.length > 0 && !allSelected;

  const handleToggleAll = (checked) => {
    if (checked) {
      setSelectedIds(allRowIds);
    } else {
      setSelectedIds([]);
    }
  };

  const handleToggleOne = (id, checked) => {
    setSelectedIds((prev) => {
      if (checked) {
        return prev.includes(id) ? prev : [...prev, id];
      }
      return prev.filter((item) => item !== id);
    });
  };

  const toolbarActions = [
    {
      key: 'delete',
      icon: Trash2,
      label: '批量删除',
      variant: 'destructive',
      onClick: () => {
        if (selectedIds.length === 0) {
          toast.warning('请先选择需要删除的权限');
          return;
        }
        batchDeleteMutation.mutate({ ids: selectedIds });
      },
      disabled:
        selectedIds.length === 0 || batchDeleteMutation.isPending,
    },
  ];

  return (
    <Container>
      <div className="flex flex-wrap items-center justify-between gap-3 mb-6">
        <div>
          <h1 className="text-3xl font-bold flex items-center gap-2">
            <ScrollText className="size-6 text-primary" />
            权限管理
          </h1>
          <p className="text-muted-foreground mt-1">
            查看权限清单，按资源模块、动作类型等条件筛选
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Button
            variant="outline"
            onClick={() => refetch()}
            disabled={isLoading}
          >
            <RefreshCw className="size-4 mr-2" />
            刷新
          </Button>
          <Button onClick={() => setIsCreateDialogOpen(true)}>
            <Plus className="size-4 mr-1.5" />
            新建权限
          </Button>
        </div>
      </div>

      <Card>
        <CardHeader>
          <CardTitle>权限列表</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid grid-cols-1 lg:grid-cols-5 gap-4">
            <div className="col-span-1 lg:col-span-2 relative">
              <Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                placeholder="搜索权限名称 / 标识 / 描述"
                value={keyword}
                onChange={(event) => {
                  setKeyword(event.target.value);
                  setPage(1);
                }}
                className="pl-10"
              />
            </div>

            <Select
              value={resource}
              onValueChange={(value) => {
                setResource(value);
                setPage(1);
              }}
            >
              <SelectTrigger>
                <SelectValue placeholder="所属模块" />
              </SelectTrigger>
              <SelectContent>
                {resourceOptions.map((option) => (
                  <SelectItem key={option} value={option}>
                    {option === 'all' ? '全部模块' : option}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            <Select
              value={action}
              onValueChange={(value) => {
                setAction(value);
                setPage(1);
              }}
            >
              <SelectTrigger>
                <SelectValue placeholder="动作类型" />
              </SelectTrigger>
              <SelectContent>
                {actionOptions.map((option) => (
                  <SelectItem key={option} value={option}>
                    {option === 'all' ? '全部动作' : option}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            <Select
              value={category}
              onValueChange={(value) => {
                setCategory(value);
                setPage(1);
              }}
            >
              <SelectTrigger>
                <SelectValue placeholder="权限分类" />
              </SelectTrigger>
              <SelectContent>
                {categoryOptions.map((option) => (
                  <SelectItem key={option} value={option}>
                    {option === 'all' ? '全部分类' : option}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            <Button
              variant="outline"
              onClick={() => {
                setKeyword('');
                setResource('all');
                setAction('all');
                setCategory('all');
                setPage(1);
              }}
            >
              清除筛选
            </Button>
          </div>

          <BatchActionBar
            selectedCount={selectedIds.length}
            onClear={() => setSelectedIds([])}
            actions={toolbarActions}
          />

          <ResponsiveTable>
            <ResponsiveTableHeader>
              <ResponsiveTableRow>
                <ResponsiveTableHead className="w-[48px]">
                  <Checkbox
                    checked={
                      allSelected ? true : partiallySelected ? 'indeterminate' : false
                    }
                    onCheckedChange={handleToggleAll}
                    aria-label="选择全部"
                  />
                </ResponsiveTableHead>
                <ResponsiveTableHead>权限名称</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>权限标识</ResponsiveTableHead>
                <ResponsiveTableHead hideOnTablet>资源模块</ResponsiveTableHead>
                <ResponsiveTableHead hideOnTablet>动作</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>分类</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>创建时间</ResponsiveTableHead>
                <ResponsiveTableHead className="w-[100px] text-right">
                  操作
                </ResponsiveTableHead>
              </ResponsiveTableRow>
            </ResponsiveTableHeader>

            <TableBody>
              {isLoading ? (
                <TableLoading rows={5} columns={8} />
              ) : error ? (
                <ResponsiveTableRow>
                  <ResponsiveTableCell colSpan={8} className="text-center py-10">
                    <p className="text-destructive mb-4">
                      加载失败：{error.message}
                    </p>
                    <Button variant="outline" onClick={() => refetch()}>
                      重试
                    </Button>
                  </ResponsiveTableCell>
                </ResponsiveTableRow>
              ) : permissions.length === 0 ? (
                <TableEmpty
                  colSpan={8}
                  icon={ScrollText}
                  title="暂无权限数据"
                  description="检查筛选条件或稍后再试。"
                />
              ) : (
                permissions.map((permission) => {
                  const selected = selectedIds.includes(permission.id);
                  return (
                    <ResponsiveTableRow key={permission.id}>
                      <ResponsiveTableCell className="w-[48px]">
                        <Checkbox
                          checked={selected}
                          onCheckedChange={(checked) =>
                            handleToggleOne(permission.id, checked)
                          }
                        />
                      </ResponsiveTableCell>

                      <ResponsiveTableCell className="space-y-1">
                        <div className="font-medium">
                          {permission.displayName || permission.name}
                        </div>
                        {permission.description ? (
                          <div className="text-xs text-muted-foreground line-clamp-2">
                            {permission.description}
                          </div>
                        ) : null}
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnMobile>
                        <Badge variant="outline">{permission.name}</Badge>
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnTablet>
                        {permission.resource ? (
                          <Badge variant="secondary">{permission.resource}</Badge>
                        ) : (
                          <span className="text-xs text-muted-foreground">-</span>
                        )}
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnTablet>
                        {permission.action || '-'}
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnMobile>
                        {permission.category || '-'}
                      </ResponsiveTableCell>

                      <ResponsiveTableCell hideOnMobile>
                        {formatDateTime(permission.createdAt)}
                      </ResponsiveTableCell>

                      <ResponsiveTableCell className="text-right">
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button
                              variant="ghost"
                              size="icon"
                              className="h-8 w-8"
                            >
                              <EllipsisVertical className="size-4" />
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end">
                            <DropdownMenuItem
                              onClick={() => handleOpenEdit(permission.id)}
                            >
                              <Edit className="size-3.5 mr-2" />
                              编辑
                            </DropdownMenuItem>
                            <DropdownMenuItem
                              onClick={() => handleDelete(permission.id)}
                              className="text-destructive focus:text-destructive"
                            >
                              <Trash2 className="size-3.5 mr-2" />
                              删除
                            </DropdownMenuItem>
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </ResponsiveTableCell>
                    </ResponsiveTableRow>
                  );
                })
              )}
            </TableBody>
          </ResponsiveTable>

          {meta.totalPages > 1 && (
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div className="text-sm text-muted-foreground">
                第 {(meta.page - 1) * meta.pageSize + 1} -
                {' '}
                {Math.min(meta.page * meta.pageSize, meta.total)} 条 / 共 {meta.total} 条
              </div>
              <div className="flex items-center gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  disabled={meta.page <= 1}
                  onClick={() => setPage((prev) => Math.max(prev - 1, 1))}
                >
                  上一页
                </Button>
                <span className="text-sm text-muted-foreground">
                  {meta.page} / {meta.totalPages}
                </span>
                <Button
                  variant="outline"
                  size="sm"
                  disabled={meta.page >= meta.totalPages}
                  onClick={() => setPage((prev) => Math.min(prev + 1, meta.totalPages))}
                >
                  下一页
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      <FormDialog
        open={isCreateDialogOpen}
        onOpenChange={(open) => setIsCreateDialogOpen(open)}
        title="新建权限"
        description="配置权限标识、名称以及所属资源"
        size="lg"
      >
        <PermissionForm
          mode="create"
          onSubmit={(payload) => createPermissionMutation.mutate(payload)}
          onCancel={() => setIsCreateDialogOpen(false)}
          isSubmitting={createPermissionMutation.isPending}
        />
      </FormDialog>

      <FormDialog
        open={isEditDialogOpen}
        onOpenChange={(open) => {
          if (!open) {
            setIsEditDialogOpen(false);
            setEditingPermissionId(null);
            setEditingPermission(null);
          }
        }}
        title="编辑权限"
        description="调整权限名称、所属模块、分类信息"
        size="lg"
      >
        {isLoadingPermissionDetail ? (
          <div className="py-10 text-center text-sm text-muted-foreground">
            正在加载权限信息…
          </div>
        ) : editingPermission ? (
          <PermissionForm
            mode="edit"
            defaultValues={editingPermission}
            onSubmit={(payload) =>
              updatePermissionMutation.mutate({
                id: editingPermissionId,
                payload,
              })
            }
            onCancel={() => {
              setIsEditDialogOpen(false);
              setEditingPermissionId(null);
              setEditingPermission(null);
            }}
            isSubmitting={updatePermissionMutation.isPending}
            disableName={true}
          />
        ) : (
          <div className="py-10 text-center text-sm text-muted-foreground">
            未找到权限信息。
          </div>
        )}
      </FormDialog>
    </Container>
  );
}

